package com.nariano.webapp;

import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import static com.nariano.server.domain.entities.PopulationType.*;

import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.springframework.util.Assert;

import com.nariano.server.domain.engine.droolsimpl.ResourceManagementAction;
import com.nariano.server.domain.entities.City;
import com.nariano.server.domain.entities.User;
import com.nariano.server.domain.utils.PopulationTypeList;
import com.nariano.server.services.statistics.PopulationDistribution;
import com.nariano.server.services.statistics.StatsService;
import com.nariano.server.services.userservice.UserService;
import com.nariano.server.utils.spring.SpringFactory;
import com.nariano.webapp.util.ParameterizedResourceModel;

public class TopListPlayersPanel extends Panel  {
	
	private static Logger logger = Logger.getLogger(TopListPlayersPanel.class.getCanonicalName());

	public TopListPlayersPanel(String id, int maxNumbers, final User me) {
		super(id);
		
		final StatsService statsService = SpringFactory.getBean("statsService", StatsService.class);
		final UserService userService = SpringFactory.getBean("userService", UserService.class);
		
		ParameterizedResourceModel attackInfo = new ParameterizedResourceModel("attackInfo", getOpponentUserName(me, userService));
		ParameterizedResourceModel attackedByInfo = new ParameterizedResourceModel("attackedByInfo", getAttackerUserNames(me, userService));
	
		add(new Label("attackInfo", attackInfo){
			@Override
            public boolean isVisible() {
                return me != null;
            }
		});
		add(new Label("attackedByInfo", attackedByInfo){
			@Override
            public boolean isVisible() {
                return me != null;
            }
		});
	    RepeatingView rv = new RepeatingView("rv");
	    add(rv);
	    List<City> topList = statsService.getTopList(maxNumbers);
	    for (final City  city : topList) {
	    	final boolean loggedIn = NarianoSession.get().isAuthenticied() == true;
	    	
	    	WebMarkupContainer parent = new WebMarkupContainer(rv.newChildId());
	    	rv.add(parent);
	    	final User user = userService.findUserFromId(city.getOwnerId());
			parent.add(new Label("playerNotLoggedIn", getUserName(user)){

				@Override
				public boolean isVisible() {
					return loggedIn==false;
				}
	    		
	    	});
	    	
	    	Link link = new Link("edit") {

				@Override
				public void onClick() {
					setResponsePage(new Index(user));
					
				}};
			parent.add(link );
			link.add(new Label("playerLoggedIn", user.getUserName().replaceFirst("^.:", "")){

				@Override
				public boolean isVisible() {
					return loggedIn==true;
				}
	    		
	    	});
			
	    	parent.add(new Label("points", getUserPoints(user)));
	    	PopulationDistribution populationDistribution = statsService.getPopulationDistribution(user);
			parent.add(new Label("demography", getPopulation(populationDistribution)));
	    	parent.add(new Label("warpower", getWarpower(populationDistribution)));
	    	parent.add(new Label("resources", getResources(user, populationDistribution)));
	    	
	    }
	    
		
	}

	String [] WAR_LEVEL = { "-", "*", "**", "***", "****"};
	String [] RESOURCE_LEVEL = { "-", "*", "**", "***", "****"};

	private String getWarpower(PopulationDistribution distr) {
		int warPower = distr.getWarPower();
		if (warPower<=0) {
			return WAR_LEVEL[0];
		}
		float factor = (float)warPower / distr.getPoupulationCount();
		int index = 1 + (int)(factor*4);
		if (index>=WAR_LEVEL.length) {
			logger.severe("Upps " + index + " " + factor + " "+ distr);
			index = WAR_LEVEL.length-1;
		}
		return WAR_LEVEL[index];
	}

	private String getResources(User user, PopulationDistribution distr) {
		int resources = user.getResources();
		if (resources<=0) {
			return RESOURCE_LEVEL[0];
		}
		float factor = (float)resources / (distr.getPoupulationCount()*ResourceManagementAction.MAX_RESOURCES_FACTOR);
		factor = Math.min(factor, 0.99f);
		int index = 1 + (int)(factor*4);
		if (index>=RESOURCE_LEVEL.length) {
			logger.severe("Upps " + index + " resources:" + resources + " " + factor + " "+ distr );
			index = RESOURCE_LEVEL.length-1;
		}
		return RESOURCE_LEVEL[index];
	}

	private String getPopulation(PopulationDistribution distr) {
		return String.format("%d/%d/%d/%d", distr.getPoupulationCount(PEASENT),
				distr.getPoupulationCount(PRIEST),
				distr.getPoupulationCount(SOLDIER),
				distr.getPoupulationCount(KNIGTH));
	}

	private String getUserPoints(User user) {
		return String.format("%d", user.getPoints());
	}

	private String getUserName(User user) {
		return String.format("%s", user.getUserName().replaceFirst("^.:", ""));
	}
	
	private String getOpponentUserName(User me, UserService userService) {
		return me==null?"-":getUserName2(userService.findUserFromId(me.getEnemyUserId()));
	}

	private String getUserName2(User opponent) {
		return opponent==null?"-":opponent.getUserName();
	}
	
	private String getAttackerUserNames(User me, UserService userService) {
		if (me==null) {
			return "";
		}
		List<User> list = userService.findAttackers(me.getId());
		if (list.isEmpty()) {
			return "-";
		}
		String res = "";
		for (Iterator<User> iter = list.iterator(); iter.hasNext();) {
			User u = iter.next();
			res += u.getUserName();
			if (iter.hasNext()) {
				res += " ,";
			}
		}
		return res;
	}


}
